//--------------------------------------------------------------------------------------------------------------------
//Open Source Smart for Home (OSS4Home)
//
//The MIT License (MIT)
//
//Copyright (c) 2015 Sascha Deeg, Kim Janek Triebig, Michael Etter
//
//Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
//documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 
//rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
//permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in all copies or substantial portions of
//the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
//BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
//NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
//DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//--------------------------------------------------------------------------------------------------------------------

package de.oss4home.cc.wshandler;

import java.util.List;

import javax.ws.rs.client.Client;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status.Family;

import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.client.JerseyClientBuilder;
import org.glassfish.jersey.jackson.JacksonFeature;

import de.oss4home.exceptions.OSS4HomeControllerWSException;
import de.oss4home.bc.dto.BcDeviceConfigDTO;
import de.oss4home.bc.dto.BcDeviceValueDTO;
import de.oss4home.bc.dto.ControllerVersionDTO;

public class ControllerWsHandler {
	private String connectionString;
	private ClientConfig cc = null;
	private Client client = null;
	private WebTarget maintarget = null;
	public ControllerWsHandler(String connectionString) {
		this.connectionString = connectionString;
		cc = new ClientConfig().register(new JacksonFeature());
		client = JerseyClientBuilder.newClient(cc);
		maintarget = client.target(connectionString);

	}

	public List<BcDeviceValueDTO> getDeviceValue() throws OSS4HomeControllerWSException {
		try {
			WebTarget target = maintarget.path("devices").path("values");
			List<BcDeviceValueDTO> ret = target.request(MediaType.APPLICATION_JSON)
					.get(new GenericType<List<BcDeviceValueDTO>>() {
					});
			return ret;
		} catch (Exception ex) {
			String message = "Fehler beim Abruf der Devices vom Controller ," + "ConnectionString: " + connectionString;
			throw new OSS4HomeControllerWSException(message, ex);
		}
	}

	public void setDeviceValue(BcDeviceValueDTO value) throws OSS4HomeControllerWSException {
		Response returnValue = null;
		try {
			WebTarget target = maintarget.path("devices").path("values");
			returnValue = target.request(MediaType.APPLICATION_JSON)
					.put(Entity.entity(value, MediaType.APPLICATION_JSON), Response.class);

		} catch (Exception ex) {
			String message = "Fehler beim Aktualisieren des Device Values am Controller ," + "ConnectionString: "
					+ connectionString + "DeviceID: " + value.getId();
			throw new OSS4HomeControllerWSException(message, ex);
		}
		if (returnValue.getStatusInfo().getFamily() != Family.SUCCESSFUL) {
			String message = "Fehler beim Aktualisieren des Device Values am Controller ," + " " + "ConnectionString: "
					+ connectionString + " " + "DeviceID: " + value.getId() + " " + "StatusCode :"
					+ returnValue.getStatusInfo().getStatusCode();
			throw new OSS4HomeControllerWSException(message);

		}

	}

	public List<BcDeviceConfigDTO> getDeviceConfig() throws OSS4HomeControllerWSException {
		try {
			WebTarget target = maintarget.path("devices").path("config");
			List<BcDeviceConfigDTO> ret = target.request(MediaType.APPLICATION_JSON)
					.get(new GenericType<List<BcDeviceConfigDTO>>() {
					});
			return ret;
		} catch (Exception ex) {
			String message = "Fehler beim Abruf der Devices vom Controller ," + "ConnectionString: " + connectionString;
			throw new OSS4HomeControllerWSException(message, ex);
		}
	}

	public void updateDeviceConfig(BcDeviceConfigDTO data) throws OSS4HomeControllerWSException {
		Response returnValue = null;
		try {
			WebTarget target = maintarget.path("devices").path("config");
			returnValue = target.request(MediaType.APPLICATION_JSON)
					.put(Entity.entity(data, MediaType.APPLICATION_JSON), Response.class);
		} catch (Exception ex) {
			String message = "Fehler beim Aktualisieren der Konfiguration am Controller ," + "ConnectionString: "
					+ connectionString + "DeviceID: " + data.getId();
			throw new OSS4HomeControllerWSException(message, ex);
		}
		if (returnValue.getStatusInfo().getFamily() != Family.SUCCESSFUL) {
			String message = "Fehler beim Aktualisieren der Konfiguration am Controller ," + " " + "ConnectionString: "
					+ connectionString + " " + "DeviceID: " + data.getId() + " " + "StatusCode :"
					+ returnValue.getStatusInfo().getStatusCode();
			throw new OSS4HomeControllerWSException(message);

		}

	}

	public ControllerVersionDTO getVersionInfos() throws OSS4HomeControllerWSException {
		try {
			WebTarget target = maintarget.path("version");
			ControllerVersionDTO ret = target.request(MediaType.APPLICATION_JSON)
					.get(new GenericType<ControllerVersionDTO>() {
					});
			return ret;
		} catch (Exception ex) {
			String message = "Fehler beim Abruf der Controller Version ," + "ConnectionString: " + connectionString;
			throw new OSS4HomeControllerWSException(message, ex);
		}
	}

}
